package net.ib.mtalk.ui.adapter;

import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.provider.ContactsContract.Contacts;
import android.support.v4.widget.CursorAdapter;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;

public class MTalkCursorAdapter extends CursorAdapter {
	
	private int mLayout;
    private int mDropDownLayout;
    
    private LayoutInflater mInflater;
    
    protected int[] mFrom;
    protected int[] mTo;
    
    private int mStringConversionColumn;
    private CursorToStringConverter mCursorToStringConverter;
    private ViewBinder mViewBinder;
    private String[] mOriginalFrom;
    
    @SuppressWarnings("deprecation")
	public MTalkCursorAdapter(Context context, int layout, Cursor c, String[] from, int[] to) {
		super(context, c);
		mLayout = mDropDownLayout = layout;
		mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
		mStringConversionColumn = -1;
		mTo = to;
		mOriginalFrom = from;
		findCoumns(from);
	}
    
	public MTalkCursorAdapter(Context context, int layout, Cursor c, String[] from, int[] to, int flag) {
		super(context, c, flag);
		mLayout = mDropDownLayout = layout;
		mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
		mStringConversionColumn = -1;
		mTo = to;
		mOriginalFrom = from;
		findCoumns(from);
	}

	@Override
	public View newView(Context context, Cursor cursor, ViewGroup parent) {
		return mInflater.inflate(mLayout, parent, false);
	}
	
	@Override
	public View newDropDownView(Context context, Cursor cursor, ViewGroup parent) {
		return mInflater.inflate(mDropDownLayout, parent, false);
	}
	
	@Override
	public void bindView(View view, Context context, Cursor cursor){
		final ViewBinder binder = mViewBinder;
		final int count = mTo.length;
		final int[] from = mFrom;
		final int[] to = mTo;
		
		for(int i=0; i<count; i++){
			final View v = view.findViewById(to[i]);
			if(v == null){
				continue;
			}
			boolean bound = false;
			if(binder != null){
				bound = binder.setViewValue(v, cursor, from[i]);
			}
			
			if(bound){
				continue;
			}
			String text = cursor.getString(from[i]);
			if(text == null){
				text = "";
			}
			if(v instanceof TextView){
				setViewText((TextView) v, text);
				continue;
			}else if(v instanceof ImageView){
				setViewImage((ImageView)v, text);
				continue;
			}else if(v instanceof EditText){						
				continue;
			}else{
				throw new IllegalStateException((new StringBuilder())
						.append(" is not a")
						.append(" view that can be bounds by this MTalkCursorAdapter")
						.toString());
			}
		}
	}
	
	public ViewBinder getViewBinder(){
		return mViewBinder;
	}
	
	public void setViewBinder(ViewBinder viewBinder){
		mViewBinder = viewBinder;
	}
	
	public void setViewImage(ImageView v, String value){
		try{
			v.setImageResource(Integer.parseInt(value));
		}catch(NumberFormatException nfe){
			v.setImageURI(Uri.parse(value));
		}
	}
	
	public void setViewText(TextView v, String text){
		v.setText(text);
	}
	
	public int getStringConversionColumn(){
		return mStringConversionColumn;
	}
	
	public void setStringConversionColumn(int stringConversionColumn){
		mStringConversionColumn = stringConversionColumn;
	}
	
	public CursorToStringConverter getCursorToStringConverter(){
		return mCursorToStringConverter;
	}
	
	public void setCursorToStringConverter(CursorToStringConverter cursorToStringConverter){
		mCursorToStringConverter = cursorToStringConverter;
	}
	
	@Override
	public CharSequence convertToString(Cursor cursor) {
		if (mCursorToStringConverter != null){
			return mCursorToStringConverter.convertToString(cursor);
		}else if(mStringConversionColumn > -1){
			return cursor.getString(mStringConversionColumn);
		}else{
			return super.convertToString(cursor);
		}
	}
	
	private void findCoumns(String[] from){
		if(mCursor != null){
			int count = from.length;
			if(mFrom == null || mFrom.length != count){
				mFrom = new int[count];
			}
			for(int i = 0; i< count; i++){
				mFrom[i] = mCursor.getColumnIndexOrThrow(from[i]);
			}
		}else{
			mFrom = null;
		}
	}
	
	@Override
	public void changeCursor(Cursor cursor) {
		super.changeCursor(cursor);
		findCoumns(mOriginalFrom);
	}
	
	@Override
	public Cursor swapCursor(Cursor c) {
		Cursor res = super.swapCursor(c);
		findCoumns(mOriginalFrom);
		return res;
	}
	
	public void changeCursorAndColumns(Cursor c, String[] from, int[] to){
		mOriginalFrom = from;
		mTo = to;
		super.changeCursor(c);
		findCoumns(mOriginalFrom);
	}
	
	public static interface ViewBinder{
		public abstract boolean setViewValue(View view, Cursor cursor, int columnIndex);
	}
	
	public static interface CursorToStringConverter{
		public abstract CharSequence convertToString(Cursor cursor);
	}
	
	public void setViewResource(int layout){
		mLayout = layout;
	}
	
	public void setDropDownViewResource(int dropDownLayout){
		mDropDownLayout = dropDownLayout;
	}
}
